﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BasicClass;
using System.Threading;

namespace DealPLC
{
    /// <summary>
    /// 写入的仿真信息
    /// </summary>
    [Serializable]
    public class WriteInfo_PLCSim : BaseClass
    {
        #region 静态类示例
        public static WriteInfo_PLCSim W_I = new WriteInfo_PLCSim();
        #endregion 静态类示例

        #region 定义
        public string Reg { set; get; }
        public string RegTri { set; get; }//触发寄存器
        public string Value { set; get; }
        public string Time { set; get; }

        public bool BlSim = false;//是否处于仿真状态

        public List<WriteInfo_PLCSim> WriteInfo_Info_L = new List<WriteInfo_PLCSim>();

        public string CurTime//当前时间
        {
            get
            {
                return DateTime.Now.ToShortTimeString();
            }
        }

        //mutex
        public Mutex Mt_Write = new Mutex();
        #endregion 定义


        /// <summary>
        /// 记录写的内容
        /// </summary>
        public void WriteInfo<T>(string reg, T value)
        {
            Mt_Write.WaitOne();
            try
            {
                if (!BlSim)
                {
                    return;
                }
                WriteInfo_Info_L.Add(new WriteInfo_PLCSim()
                {
                    Reg = reg,
                    RegTri = reg,//假设单个寄存器都是触发寄存器
                    Value = value.ToString(),
                    Time = CurTime,
                });

                //判断写入的寄存器是否包含了对触发寄存器的清除
                ClearTriggerValue(reg, double.Parse(value.ToString()));
            }
            catch (Exception ex)
            {
                Log.L_I.WriteError(NameClass, ex);
            }
            finally
            {
                Mt_Write.ReleaseMutex();
            }
        }

        /// <summary>
        /// 判断，清除模拟寄存器对应数组中的值
        /// </summary>
        bool ClearTriggerValue(string reg, double value)
        {
            try
            {
                if (!reg.EndsWith("\\n"))
                {
                    reg = reg + "\\n";
                }
                //如果写入的寄存器保护的是触发寄存器，对应的数值写入
                int index = -1;
                for (int j = 0; j < RegMonitor.R_I.Reg_L.Count; j++)
                {
                    if (RegMonitor.R_I.Reg_L[j].NameReg == reg)
                    {
                        index = j;
                        break;
                    }
                }
                if (index == -1)
                {
                    return false;
                }
                ParLogicPLC.P_I.intTrrigerValue[index] = (int)value;//数组按照单个寄存器

                //重新赋值
                LogicPLC.L_I.ManualTrriger();//赋值触发的时候方法中的Old变量
                return true;
            }
            catch (Exception ex)
            {
                Log.L_I.WriteError(NameClass, ex);
                return false;
            }
        }

        /// <summary>
        /// 记录写的内容
        /// </summary>
        /// <param name="reg"></param>
        /// <param name="value"></param>
        public void WriteInfo<T>(string reg, T[] value)
        {
            Mt_Write.WaitOne();
            try
            {
                if (!BlSim)
                {
                    return;
                }

                WriteInfo_PLCSim w = new WriteInfo_PLCSim()
                {
                    Reg = reg,
                    Value = string.Join("-", value),
                    Time = CurTime,
                };

                //判断写入的寄存器是否包含了对触发寄存器的清除
                string[] regs = Array.ConvertAll<string, string>(reg.Split('\n'), Convert.ToString);
                for (int i = 0; i < value.Length; i++)
                {
                    if (ClearTriggerValue(regs[i] + "\\n", (int)double.Parse(value[i].ToString())))
                    {
                        w.RegTri = regs[i] + "\\n";//专门用来判断是否是触发寄存器的
                    }
                }

                WriteInfo_Info_L.Add(w);

            }
            catch (Exception ex)
            {
                Log.L_I.WriteError(NameClass, ex);
            }
            finally
            {
                Mt_Write.ReleaseMutex();
            }
        }
    }

    /// <summary>
    /// 等待被清除
    /// </summary>
    [Serializable]
    public class WaitforClear
    {
        #region 静态类示例
        public static WaitforClear W_I = new WaitforClear();
        #endregion 静态类示例


        public List<WaitforClear> W_L = new List<WaitforClear>();

        public int Count
        {
            get
            {
                return W_L.Count;
            }
        }
        public string Reg { set; get; }//等待的寄存器
        public int Time { set; get; }//等待的时间
        public long Time_Init { set; get; }//触发开始的时间

        /// <summary>
        /// 索引器
        /// </summary>
        public WaitforClear this[int index]
        {
            get
            {
                return W_L[index];
            }
        }

        public void Add(WaitforClear w)
        {
            W_L.Add(w);
        }

        public void Remove(int i)
        {
            W_L.RemoveAt(i);
        }

        /// <summary>
        /// 清空列表
        /// </summary>
        public void Clear()
        {
            W_L.Clear();
        }
    }

    /// <summary>
    /// 数据流转方向
    /// </summary>
    public enum DataFlow_enum
    {
        Error,
        PLCtoPC,
        PCtoPLC,

    }

   
}
